//
// comet client javascript
// 
// @author krdlab
//


// 例外オブジェクト作成 (global...orz)
var new_error = function(message) {
  return new Error(message);
};

// JSON 化
var to_json = function(obj) {
  return JSON.stringify(obj);
};

// Object 化
var parse_json = function(json) {
  return JSON.parse(json);
};


// Comet クライアントのプロトタイプ生成
// 
// spec:
//    construction 引数が格納されたハッシュ
//      end_point: 接続先 URI (必須)
//
var create_comet_client = function(spec) {
  if (!spec) {
    throw new_error(
        "illegal argument! (function=create_comet_client)");
  }

  var that = {};

  // この function 定義は定石
  that.create_httprequest = function() {
    if (window.ActiveXObject) {
      try {
        return new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        try {
          return new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e2) {
          return null;
        }
      }
    } else if (window.XMLHttpRequest) {
      return new XMLHttpRequest();
    } else {
      return null;
    }
  };

  // 必須
  spec.wait_req = that.create_httprequest();
  spec.post_req = that.create_httprequest();
  if (!spec.wait_req || !spec.post_req) {
    throw new_error(
        "failed create HttpRequest! (function=create_comet_client)");
  }

  // WAIT
  that.wait_response = function() {
    spec.wait_req.abort();
    // ↓パラメータは server により規定
    spec.wait_req.open('GET', spec.end_point + '?type=wait', true); 
    spec.wait_req.onreadystatechange = function() {
      if (spec.wait_req.readyState == 4) {
        if (spec.wait_req.status == 200) {
          // JSON を Object 化しておく
          spec.wait_req.responseData = parse_json(spec.wait_req.responseText);
          that.on_wait_success(spec.wait_req);
        } else {
          that.on_wait_failure(spec.wait_req);
        }
        that.on_wait_complete(spec.wait_req);
      }
    }
    spec.wait_req.send(null);
  };
  that.on_wait_success  = function(req) {};
  that.on_wait_failure  = function(req) {};
  that.on_wait_complete = function(req) {};

  // POST
  that.post_data = function(data) {
    spec.post_req.abort();
    spec.post_req.open('POST', spec.end_point, true);
    spec.post_req.setRequestHeader('Content-Type',
        'application/x-www-form-urlencoded;charset=UTF-8');
    spec.post_req.send('json=' + to_json(data));
  };
  that.on_post_success  = function(req) {}; // XXX 今は使えないよ
  that.on_post_failure  = function(req) {}; // XXX 今は使えないよ
  that.on_post_complete = function(req) {}; // XXX 今は使えないよ

  // STOP
  that.stop = function() {
    spec.wait_req.abort();
    spec.post_req.abort();
  };
  return that;
};

